home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1999 March / EnigmA AMIGA RUN 35 (1999)(G.R. Edizioni)(IT)[!][issue 1999-03].iso / earcd / devel / flash-0.4.3 / plugin / plugin.c < prev   
Text File  |  1999-01-01  |  10KB  |  477 lines

  1. /******************************************************************************
  2.  * Copyright (c) 1996 Netscape Communications. All rights reserved.
  3.  ******************************************************************************/
  4.  
  5. /*
  6.  *    Modifications for the Linux Flash Plugin
  7.  *    by Olivier Debon <odebon@club-internet.fr>
  8.  */
  9.  
  10. static char *rcsid = "$Id: plugin.c,v 1.10 1998/12/06 18:31:53 olivier Exp olivier $";
  11.  
  12. #include <stdio.h>
  13. #include "npapi.h"
  14.  
  15. #include "flash.h"
  16. #include <X11/Intrinsic.h>
  17. #include <X11/IntrinsicP.h>
  18. #include <X11/Core.h>
  19. #include <X11/CoreP.h>
  20.  
  21. typedef struct _PluginInstance
  22. {
  23.     char        *flashData;
  24.     long           size;
  25.     long          nbChunks;
  26.     long          gInitDone;
  27.     Display     *dpy;
  28.     GC         gc;
  29.     Window          win;
  30.     Widget          widget;
  31.     XtIntervalId      timer;
  32.     struct timeval      wd;
  33.     long            attributes;
  34.     FlashHandle      fh;
  35. } PluginInstance;
  36.  
  37. static void updateTimer(PluginInstance* This);
  38. static void flashEvent(Widget w, XtPointer client_data, XEvent *event, Boolean *dispatch);
  39. static void flashWakeUp(XtPointer client_data, XtIntervalId *id);
  40. static void getUrl( char * url, char *target, void *client_data);
  41. static long parseAttributes(int16 n, char *argn[], char *argv[]);
  42.  
  43. #ifdef C6R5
  44. // Ugly but it makes it work if it is compiled on
  45. // a libc6 system and running with a libc5-netscape
  46. int __sigsetjmp()
  47. {
  48.     return 0;
  49. }
  50. #endif
  51.  
  52. char*
  53. NPP_GetMIMEDescription(void)
  54. {
  55.     return("application/x-shockwave-flash:swf:Flash Plugin;application/futuresplash:spl:Future Splash");
  56. }
  57.  
  58. NPError
  59. NPP_GetValue(void *future, NPPVariable variable, void *value)
  60. {
  61.     NPError err = NPERR_NO_ERROR;
  62.  
  63.     switch (variable) {
  64.         case NPPVpluginNameString:
  65.             *((char **)value) = PLUGIN_NAME;
  66.             break;
  67.         case NPPVpluginDescriptionString:
  68.             *((char **)value) = "Flash file player " FLASH_VERSION_STRING
  69.                         "<P>Shockwave is a trademark of <A HREF=\"http://www.macromedia.com\">Macromedia®</A>"
  70.                         "<P>Author : <A HREF=mailto:odebon@club-internet.fr>Olivier Debon </A>";
  71.             break;
  72.         default:
  73.             err = NPERR_GENERIC_ERROR;
  74.     }
  75.     return err;
  76. }
  77.  
  78. NPError
  79. NPP_Initialize(void)
  80. {
  81.     freopen("/dev/tty","w",stdout);
  82.     freopen("/dev/tty","w",stderr);
  83.     return NPERR_NO_ERROR;
  84. }
  85.  
  86.  
  87. jref
  88. NPP_GetJavaClass()
  89. {
  90.     return NULL;
  91. }
  92.  
  93. void
  94. NPP_Shutdown(void)
  95. {
  96. }
  97.  
  98.  
  99. NPError 
  100. NPP_New(NPMIMEType pluginType,
  101.     NPP instance,
  102.     uint16 mode,
  103.     int16 argc,
  104.     char* argn[],
  105.     char* argv[],
  106.     NPSavedData* saved)
  107. {
  108.         PluginInstance* This;
  109.  
  110.     if (instance == NULL)
  111.         return NPERR_INVALID_INSTANCE_ERROR;
  112.         
  113.     instance->pdata = NPN_MemAlloc(sizeof(PluginInstance));
  114.     
  115.     This = (PluginInstance*) instance->pdata;
  116.  
  117.     if (This != NULL)
  118.     {
  119.         This->flashData = 0;
  120.         This->size = 0;
  121.         This->nbChunks = 0;
  122.         This->fh = 0;
  123.         This->gInitDone = 0;
  124.         This->dpy = 0;
  125.         This->win = 0;
  126.         This->timer = 0;
  127.         This->attributes = parseAttributes(argc, argn, argv);
  128.  
  129.         return NPERR_NO_ERROR;
  130.     }
  131.     else
  132.         return NPERR_OUT_OF_MEMORY_ERROR;
  133. }
  134.  
  135.  
  136. NPError 
  137. NPP_Destroy(NPP instance, NPSavedData** save)
  138. {
  139.     PluginInstance* This;
  140.  
  141.     if (instance == NULL)
  142.         return NPERR_INVALID_INSTANCE_ERROR;
  143.  
  144.     This = (PluginInstance*) instance->pdata;
  145.  
  146.     if (This != NULL) {
  147.         if (This->timer) {
  148.             XtRemoveTimeOut(This->timer);
  149.             This->timer = 0;
  150.         }
  151.         if (This->fh) {
  152.             FlashClose(This->fh);
  153.         }
  154.         if (This->flashData) {
  155.             free(This->flashData);
  156.         }
  157.         This->fh = 0;
  158.         NPN_MemFree(instance->pdata);
  159.         instance->pdata = NULL;
  160.     }
  161.  
  162.     return NPERR_NO_ERROR;
  163. }
  164.  
  165. static void
  166. updateTimer(PluginInstance* This)
  167. {
  168.     XtAppContext ctxt;
  169.     struct timeval now;
  170.     long delay;
  171.  
  172.     if (This->timer) {
  173.         XtRemoveTimeOut(This->timer);
  174.     }
  175.  
  176.     gettimeofday(&now,0);
  177.     delay = (This->wd.tv_sec-now.tv_sec)*1000 + (This->wd.tv_usec-now.tv_usec)/1000;
  178.  
  179.     //fprintf(stderr,"Wakeup in %d ms\n", delay);
  180.  
  181.     if (delay <0) {
  182.         // OVERRUN !!!
  183.         delay = 20;    // Leave 20 ms
  184.     }
  185.     ctxt = XtWidgetToApplicationContext(This->widget);
  186.     This->timer = XtAppAddTimeOut(ctxt, delay,
  187.                 (XtTimerCallbackProc) flashWakeUp,
  188.                 (XtPointer) This);
  189. }
  190.  
  191. static void
  192. flashEvent(Widget w, XtPointer client_data, XEvent *event, Boolean *dispatch)
  193. {
  194.     PluginInstance* This;
  195.     long cmd;
  196.     long wakeUp;
  197.  
  198.     This = (PluginInstance*)client_data;
  199.  
  200.     if (This->fh) {
  201.         cmd = FLASH_EVENT;
  202.         wakeUp = FlashExec(This->fh, cmd, event, &This->wd);
  203.         if (wakeUp) {
  204.             updateTimer(This);
  205.         }
  206.     }
  207. }
  208.  
  209. static void
  210. flashWakeUp(XtPointer client_data, XtIntervalId *id)
  211. {
  212.     PluginInstance* This;
  213.     long cmd;
  214.     long wakeUp;
  215.  
  216.     This = (PluginInstance*)client_data;
  217.  
  218.     if (This->fh) {
  219.         cmd = FLASH_WAKEUP;
  220.         wakeUp = FlashExec(This->fh, cmd, 0, &This->wd);
  221.  
  222.         /* If have to wake up next time */
  223.         if (wakeUp) {
  224.             updateTimer(This);
  225.         } else {
  226.             if (This->timer) {
  227.                 XtRemoveTimeOut(This->timer);
  228.             }
  229.             This->timer = 0;
  230.         }
  231.     }
  232. }
  233.  
  234. NPError 
  235. NPP_SetWindow(NPP instance, NPWindow* window)
  236. {
  237.     PluginInstance* This;
  238.     NPSetWindowCallbackStruct *ws;
  239.     Window frame;
  240.     XWindowAttributes xwa;
  241.  
  242.     if (instance == NULL)
  243.         return NPERR_INVALID_INSTANCE_ERROR;
  244.  
  245.     if (window == NULL)
  246.         return NPERR_NO_ERROR;
  247.  
  248.     This = (PluginInstance*) instance->pdata;
  249.  
  250.     This->win = (Window) window->window;
  251.     ws = (NPSetWindowCallbackStruct *)window->ws_info;
  252.     This->dpy = ws->display;
  253.     This->gc = DefaultGC(This->dpy, DefaultScreen(This->dpy));
  254.     This->widget = XtWindowToWidget(This->dpy,This->win);
  255.  
  256.     XGetWindowAttributes(This->dpy, This->win, &xwa);
  257.  
  258.     if (!This->gInitDone && This->fh) {
  259.         FlashGraphicInit(This->fh, This->dpy, This->win);
  260.         XtAddEventHandler(This->widget, FLASH_XEVENT_MASK,
  261.                   True, (XtEventHandler) flashEvent, (XtPointer)This);
  262.         This->gInitDone = 1;
  263.  
  264.         flashWakeUp((XtPointer)This, 0);
  265.     }
  266.  
  267.  
  268.     return NPERR_NO_ERROR;
  269. }
  270.  
  271. NPError 
  272. NPP_NewStream(NPP instance,
  273.               NPMIMEType type,
  274.               NPStream *stream, 
  275.               NPBool seekable,
  276.               uint16 *stype)
  277. {
  278.     NPByteRange range;
  279.     PluginInstance* This;
  280.  
  281.     if (instance == NULL)
  282.         return NPERR_INVALID_INSTANCE_ERROR;
  283.  
  284.     This = (PluginInstance*) instance->pdata;
  285.  
  286.     return NPERR_NO_ERROR;
  287. }
  288.  
  289.  
  290. #define BUFFERSIZE (16*1024)
  291.  
  292. int32 
  293. NPP_WriteReady(NPP instance, NPStream *stream)
  294. {
  295.     PluginInstance* This;
  296.  
  297.     if (instance != NULL)
  298.     {
  299.         This = (PluginInstance*) instance->pdata;
  300.  
  301.         if (This->flashData == 0) {
  302.             This->flashData = (char *) malloc(BUFFERSIZE);
  303.             This->nbChunks++;
  304.         } else {
  305.             This->nbChunks++;
  306.             This->flashData = (char *) realloc(This->flashData, This->nbChunks*BUFFERSIZE);
  307.         }
  308.  
  309.     }
  310.     return BUFFERSIZE;
  311. }
  312.  
  313.  
  314. int32 
  315. NPP_Write(NPP instance, NPStream *stream, int32 offset, int32 len, void *buffer)
  316. {
  317.     PluginInstance* This;
  318.  
  319.     if (instance != NULL)
  320.     {
  321.         This = (PluginInstance*) instance->pdata;
  322.  
  323.         memcpy(&This->flashData[offset], buffer, len);
  324.         This->size += len;
  325.  
  326.         if (This->dpy) {
  327.             XSetFunction(This->dpy, This->gc, GXinvert);
  328.             XDrawString(This->dpy, This->win,This->gc, 10, 20, "Downloading...", strlen ("Downloading..."));
  329.             XFlush(This->dpy);
  330.         }
  331.     }
  332.  
  333.     return len;        /* The number of bytes accepted */
  334. }
  335.  
  336. static void
  337. getUrl( char * url, char *target, void *client_data)
  338. {
  339.     NPP instance;
  340.  
  341.     instance = (NPP)client_data;
  342.     NPN_GetURL(instance, url, target );
  343. }
  344.  
  345. NPError 
  346. NPP_DestroyStream(NPP instance, NPStream *stream, NPError reason)
  347. {
  348.     PluginInstance* This;
  349.  
  350.     if (instance == NULL)
  351.         return NPERR_INVALID_INSTANCE_ERROR;
  352.  
  353.     if (reason != NPERR_NO_ERROR)
  354.         return NPERR_INVALID_INSTANCE_ERROR;
  355.  
  356.     This = (PluginInstance*) instance->pdata;
  357.  
  358.     This->fh = FlashParse(This->flashData, This->size);
  359.  
  360.     if (This->fh == 0) {
  361.         return NPERR_INVALID_INSTANCE_ERROR;
  362.     }
  363.  
  364.     FlashSettings(This->fh, This->attributes);
  365.  
  366.     FlashSetGetUrlMethod(This->fh, getUrl, (void*)instance);
  367.  
  368.     FlashSoundInit(This->fh, "/dev/dsp");
  369.  
  370.     if (!This->gInitDone && This->dpy) {
  371.         FlashGraphicInit(This->fh, This->dpy, This->win);
  372.         XtAddEventHandler(This->widget,
  373.                   ExposureMask|ButtonPressMask|PointerMotionMask|ButtonReleaseMask,
  374.                   True, (XtEventHandler) flashEvent, (XtPointer)This);
  375.         This->gInitDone = 1;
  376.  
  377.         flashWakeUp((XtPointer)This, 0);
  378.     }
  379.  
  380.     return NPERR_NO_ERROR;
  381. }
  382.  
  383.  
  384. void 
  385. NPP_StreamAsFile(NPP instance, NPStream *stream, const char* fname)
  386. {
  387.     PluginInstance* This;
  388.     if (instance != NULL)
  389.         This = (PluginInstance*) instance->pdata;
  390. }
  391.  
  392.  
  393. void 
  394. NPP_Print(NPP instance, NPPrint* printInfo)
  395. {
  396.     if(printInfo == NULL)
  397.         return;
  398.  
  399.     if (instance != NULL) {
  400.         PluginInstance* This = (PluginInstance*) instance->pdata;
  401.     
  402.         if (printInfo->mode == NP_FULL) {
  403.             /*
  404.              * PLUGIN DEVELOPERS:
  405.              *    If your plugin would like to take over
  406.              *    printing completely when it is in full-screen mode,
  407.              *    set printInfo->pluginPrinted to TRUE and print your
  408.              *    plugin as you see fit.  If your plugin wants Netscape
  409.              *    to handle printing in this case, set
  410.              *    printInfo->pluginPrinted to FALSE (the default) and
  411.              *    do nothing.  If you do want to handle printing
  412.              *    yourself, printOne is true if the print button
  413.              *    (as opposed to the print menu) was clicked.
  414.              *    On the Macintosh, platformPrint is a THPrint; on
  415.              *    Windows, platformPrint is a structure
  416.              *    (defined in npapi.h) containing the printer name, port,
  417.              *    etc.
  418.              */
  419.  
  420.             void* platformPrint =
  421.                 printInfo->print.fullPrint.platformPrint;
  422.             NPBool printOne =
  423.                 printInfo->print.fullPrint.printOne;
  424.             
  425.             /* Do the default*/
  426.             printInfo->print.fullPrint.pluginPrinted = FALSE;
  427.         }
  428.         else {    /* If not fullscreen, we must be embedded */
  429.             /*
  430.              * PLUGIN DEVELOPERS:
  431.              *    If your plugin is embedded, or is full-screen
  432.              *    but you returned false in pluginPrinted above, NPP_Print
  433.              *    will be called with mode == NP_EMBED.  The NPWindow
  434.              *    in the printInfo gives the location and dimensions of
  435.              *    the embedded plugin on the printed page.  On the
  436.              *    Macintosh, platformPrint is the printer port; on
  437.              *    Windows, platformPrint is the handle to the printing
  438.              *    device context.
  439.              */
  440.  
  441.             NPWindow* printWindow =
  442.                 &(printInfo->print.embedPrint.window);
  443.             void* platformPrint =
  444.                 printInfo->print.embedPrint.platformPrint;
  445.         }
  446.     }
  447. }
  448.  
  449. static
  450. long parseAttributes(int16 n, char *argn[], char *argv[])
  451. {
  452.     int16 i;
  453.     int c;
  454.     long attributes;
  455.  
  456.     for(i=0; i<n; i++)
  457.     {
  458.         if (!strcasecmp(argn[i],"loop")) {
  459.             if (!strcasecmp(argv[i],"true")) {
  460.                 attributes |= PLAYER_LOOP;
  461.             }
  462.         }
  463.         if (!strcasecmp(argn[i],"menu")) {
  464.             if (!strcasecmp(argv[i],"true")) {
  465.                 attributes |= PLAYER_MENU;
  466.             }
  467.         }
  468.         if (!strcasecmp(argn[i],"quality")) {
  469.             if (!strcasecmp(argv[i],"high")
  470.              || !strcasecmp(argv[i],"autohigh")) {
  471.                 attributes |= PLAYER_QUALITY;
  472.             }
  473.         }
  474.     }
  475.     return attributes;
  476. }
  477.